/*
  AdViEmulator - AdventureVision emulator
  Copyright (C) 2012-2013  JustBurn

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "advigl.h"
#include "settings.h"

AdViGL::AdViGL(QWidget *parent) :
	QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
{
}

void AdViGL::attachEmu(AdViEmulator *emu)
{
	avemu = emu;
}

void AdViGL::initializeGL()
{
	colRed = 1.0f;
	colGreen = 0.2f;
	colBlue = 0.2f;
	pixBar = true;

	glClearColor(0.0, 0.0, 0.0, 0.0);
	pixeltex = bindTexture(QPixmap(":/images/pixel"), GL_TEXTURE_2D);
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	glVertexPointer(3, GL_FLOAT, 0, vertices);
	glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
	glBindTexture(GL_TEXTURE_2D, pixeltex);
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}

void AdViGL::resizeGL(int width, int height)
{
	glViewport(0, 0, width, height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0.0f, 192.0f, 45.0f, -5.0f, 1.0f, 10.0f);
	glMatrixMode(GL_MODELVIEW);
}

GLfloat AdViGL::vertices[] = {0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0};
GLfloat AdViGL::texcoords[] = {0, 1, 0, 0, 1, 0, 1, 1};
GLubyte AdViGL::indices[] = {0, 1, 2, 0, 2, 3};

#define PIXEL_DECAY_VALUE	40

void AdViGL::paintGL()
{
	glClear(GL_COLOR_BUFFER_BIT);
	if (pixBar) glEnable(GL_TEXTURE_2D);
	else glDisable(GL_TEXTURE_2D);

	// Draw pixels
	glLoadIdentity();
	glTranslatef(0.0f, 0.0f, -5.0f);
	if (Settings::o.analogDisplay) {
		uint8_t *adptr;
		for (int y=0; y<40; y++) {
			for (int x=0; x<384; x++) {
				adptr = avemu->videoOutAD + x*40 + (39-y);
				glColor4f(colRed, colGreen, colBlue, (float)*adptr / 127.0f);
				//if (avemu->IsRunning()) {
				//	int decay = *adptr - Settings::o.analogDecay;
				//	if (decay < 0) decay = 0;
				//	*adptr = decay;
				//}
				glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);
				glTranslatef(0.5f, 0.0f, 0.0f);
			}
			glTranslatef(-192.0f, 1.0f, 0.0f);
		}
	} else {
		glColor4f(colRed, colGreen, colBlue, 1.0f);
		for (int y=0; y<40; y++) {
			int ry = 39 - y;
			int bt = 1 << (ry & 7);
			int yt = ry >> 3;
			for (int x=0; x<384; x++) {
				if (!(avemu->videoOut[x*5+yt] & bt)) glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indices);
				glTranslatef(0.5f, 0.0f, 0.0f);
			}
			glTranslatef(-192.0f, 1.0f, 0.0f);
		}
	}
}
